#ifndef VD_DELETE_DEVICE
#define VD_DELETE_DEVICE

# include "vd.h"

NTSTATUS VD_DeleteDevice(
		LONG		DeviceNumber
		)
{
	NTSTATUS							status;
	PDEVICE_EXTENSION					device_extension;
	PDEVICE_OBJECT						DeviceObject;	
	PDEVICE_OBJECT						next_device;
	PDEVICE_OBJECT						prev_device;
	PDEVICE_OBJECT						tmp_device;
	LARGE_INTEGER						time_out;
	USHORT								n = 1;
	KTIMER								timer;	
	
	KeInitializeTimerEx(&timer, NotificationTimer);
	time_out.QuadPart = DereferenceAttemptsDelay;
	
	DeviceObject = BaseDriverObject->DeviceObject;
	device_extension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
	
	next_device = prev_device = DeviceObject;

	while(next_device->NextDevice)
	{
	
	device_extension = (PDEVICE_EXTENSION)next_device->DeviceExtension;	
		
	if (device_extension->DeviceNumber == DeviceNumber)
	{
		

				//Write DiskStatus to Register
		status =  RtlWriteRegistryValue(
									  RTL_REGISTRY_ABSOLUTE,
									  RegPathW.Buffer,
									  REG_DISK_DEVICE_STATUS,
									  REG_SZ,
									  DiskDeviceStatus,
									  (sizeof(DiskDeviceStatus))
									  );

		if (device_extension->DeleteDevice == FALSE)
			break;

		if (!NT_SUCCESS(status))
		{
			DbgPrint("Disk status not written to register %x \n",status);
			return STATUS_UNSUCCESSFUL;
		}
	
						
		for(n = 0; n < NumberOfDereferenceAttempts; n++) 
		{
			DbgPrint("Waiting RefCount %d \n",next_device->ReferenceCount);
			KeSetTimerEx(&timer, time_out, 0, NULL);
			KeWaitForSingleObject (&timer, Executive, KernelMode, FALSE, NULL);
			if (next_device->ReferenceCount==0)
				break;
		}
			
		if (n == NumberOfDereferenceAttempts){
			DbgPrint("Unable to dereference object %d ...",next_device->ReferenceCount);
			return STATUS_UNSUCCESSFUL;
		}
			
		DiskDeviceStatus[DeviceNumber] = L'0';
		
		device_extension->terminate_thread = TRUE;		
			
		KeSetEvent(
				 &device_extension->request_event,
				 (KPRIORITY) 0,
				 FALSE
				  );

		KeWaitForSingleObject(
							device_extension->thread_pointer,
							Executive,
							KernelMode,
							FALSE,
							NULL
							 );
	
		if(next_device == prev_device)
		{
			next_device = next_device->NextDevice;
			DbgPrint("Deleting Device %d ... \n", device_extension->DeviceNumber);

			if (prev_device && KeGetCurrentIrql() <= PASSIVE_LEVEL)
				IoDeleteDevice(prev_device);
		}
			
		else
		{
			tmp_device = next_device->NextDevice;
			DbgPrint("Delete Middle Device \n");
			if(next_device && KeGetCurrentIrql() <= PASSIVE_LEVEL)
			{
				IoDeleteDevice(next_device);				
				prev_device->NextDevice = tmp_device;	
			}
		}
		break;	
		}				
		prev_device = next_device;
		next_device = next_device->NextDevice;	
	}
	
	DbgPrint("Delete Device RefCount %d /n", BaseDriverObject->DeviceObject->ReferenceCount);
	return STATUS_SUCCESS;
}
# endif